<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      //var
      console.log(a);
      var a = 10; //全局变量
      // a = "abc";
      console.log(window.a);
      var b;
      var b;
      var b;

      b = 20;
      function myFun(params) {
        var a = 100; //函数作用域
        abc = "abc"; //省略var关键字会变成全局变量
      }
      myFun();
      console.log(a);
      console.log(abc);
      //let
      //console.log(myLet);  //不存在变量提升
      let myLet = 123; //在声明之前该变量都不可用，暂时性死区
      var myLet2 = 456;
      {
        let myLet2 = "abc"; //存在作用域，只能在它所在的代码块内使用
        // let myLet2 = "hhhhh";   //同一个作用域不允许同名
        myLet2 = "ef";
      }
      console.log(myLet2);

      function func(params) {
        // let params; //不能在函数内部重新声明形参
      }
      func();
      //const 声明一个常量，一旦声明，就不能改变,保证的是变量指向的那个内存地址所保存的数据不得更改
      // console.log(myConst);//在声明之前该变量都不可用，暂时性死区
      const myConst = 20; //不存在变量提升
      // myConst = 100;
      // const b = 456;

      const obj = {}; //保证指针，内存地址不便
      obj.prop = 123;
      console.log(obj);
      // 优先使用const 其次let，避免使用var

      // js经典面试题：setTimeout+for循环组合，使用闭包循环输出1,2,3,4,5

      for (var i = 1; i <= 5; i++) {
        setTimeout(() => {
          console.log(i);  //5个6
        }, i * 1000);
      }

      //使用闭包和自执行函数,闭包也称为函数嵌套函数
      for (var i = 1; i <= 5; i++) {
        (function (i) {
          setTimeout(() => console.log(i), i * 1000);
        })(i);
      }
      console.log(i);

      //ES6使用let
      for (let i = 1; i < 6; i++) {
        setTimeout(() => {
          console.log(i);
        }, i * 1000);
      }
    </script>
  </body>
</html>
